﻿using System;
using System.IO.Ports;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.Address;
using HslCommunication.Serial;

namespace HslCommunication.Profinet.Siemens
{
	/// <summary>
	/// 西门子的MPI协议信息，注意：未测试通过，无法使用<br />
	/// Siemens MPI protocol information, note: it has not passed the test and cannot be used
	/// </summary>
	// Token: 0x0200004B RID: 75
	public class SiemensMPI : SerialDeviceBase
	{
		/// <summary>
		/// 实例化一个西门子的MPI协议对象<br />
		/// Instantiate a Siemens MPI protocol object
		/// </summary>
		// Token: 0x06000622 RID: 1570 RVA: 0x0001CA5C File Offset: 0x0001AC5C
		public SiemensMPI()
		{
			base.ByteTransform = new ReverseBytesTransform();
			base.WordLength = 2;
		}

		/// <summary>
		/// 西门子PLC的站号信息<br />
		/// Siemens PLC station number information
		/// </summary>
		// Token: 0x17000142 RID: 322
		// (get) Token: 0x06000623 RID: 1571 RVA: 0x0001CABC File Offset: 0x0001ACBC
		// (set) Token: 0x06000624 RID: 1572 RVA: 0x0001CAC4 File Offset: 0x0001ACC4
		public byte Station
		{
			get
			{
				return this.station;
			}
			set
			{
				this.station = value;
				this.readConfirm[4] = value + 128;
				this.writeConfirm[4] = value + 128;
				int num = 0;
				int num2 = 0;
				for (int i = 4; i < 12; i++)
				{
					num += (int)this.readConfirm[i];
					num2 += (int)this.writeConfirm[i];
				}
				this.readConfirm[12] = (byte)num;
				this.writeConfirm[12] = (byte)num2;
			}
		}

		/// <summary>
		/// 与PLC进行握手<br />
		/// Handshake with PLC
		/// </summary>
		/// <returns>是否握手成功</returns>
		// Token: 0x06000625 RID: 1573 RVA: 0x0001CB3C File Offset: 0x0001AD3C
		public OperateResult Handle()
		{
			OperateResult<byte[]> operateResult;
			OperateResult operateResult2;
			for (;;)
			{
				operateResult = this.SPReceived(this.sP_ReadData, true);
				bool flag = !operateResult.IsSuccess;
				if (flag)
				{
					break;
				}
				bool flag2 = operateResult.Content[0] == 220 && operateResult.Content[1] == 2 && operateResult.Content[2] == 2;
				if (flag2)
				{
					SerialPort sP_ReadData = this.sP_ReadData;
					byte[] array = new byte[3];
					array[0] = 220;
					operateResult2 = this.SPSend(sP_ReadData, array);
					bool flag3 = !operateResult2.IsSuccess;
					if (flag3)
					{
						goto Block_5;
					}
				}
				else
				{
					bool flag4 = operateResult.Content[0] == 220 && operateResult.Content[1] == 0 && operateResult.Content[2] == 2;
					if (flag4)
					{
						goto Block_8;
					}
				}
			}
			return OperateResult.CreateFailedResult<byte[]>(operateResult);
			Block_5:
			return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			Block_8:
			SerialPort sP_ReadData2 = this.sP_ReadData;
			byte[] array2 = new byte[3];
			array2[0] = 220;
			array2[1] = 2;
			OperateResult operateResult3 = this.SPSend(sP_ReadData2, array2);
			bool flag5 = !operateResult3.IsSuccess;
			OperateResult result;
			if (flag5)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
			}
			else
			{
				result = OperateResult.CreateSuccessResult();
			}
			return result;
		}

		/// <summary>
		/// 从西门子的PLC中读取数据信息，地址为"M100","AI100","I0","Q0","V100","S100"等，详细请参照API文档<br />
		/// Read data information from Siemens PLC, the address is "M100", "AI100", "I0", "Q0", "V100", "S100", etc., please refer to the API documentation
		/// </summary>
		/// <param name="address">西门子的地址数据信息</param>
		/// <param name="length">数据长度</param>
		/// <returns>带返回结果的结果对象</returns>
		// Token: 0x06000626 RID: 1574 RVA: 0x0001CC58 File Offset: 0x0001AE58
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = SiemensMPI.BuildReadCommand(this.station, address, length, false);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				bool isClearCacheBeforeRead = base.IsClearCacheBeforeRead;
				if (isClearCacheBeforeRead)
				{
					base.ClearSerialCache();
				}
				OperateResult operateResult2 = this.SPSend(this.sP_ReadData, operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
				}
				else
				{
					OperateResult<byte[]> operateResult3 = this.SPReceived(this.sP_ReadData, true);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
					}
					else
					{
						bool flag4 = operateResult3.Content[14] != 229;
						if (flag4)
						{
							result = new OperateResult<byte[]>("PLC Receive Check Failed:" + SoftBasic.ByteToHexString(operateResult3.Content));
						}
						else
						{
							operateResult3 = this.SPReceived(this.sP_ReadData, true);
							bool flag5 = !operateResult3.IsSuccess;
							if (flag5)
							{
								result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
							}
							else
							{
								bool flag6 = operateResult3.Content[19] > 0;
								if (flag6)
								{
									result = new OperateResult<byte[]>("PLC Receive Check Failed:" + operateResult3.Content[19].ToString());
								}
								else
								{
									operateResult2 = this.SPSend(this.sP_ReadData, this.readConfirm);
									bool flag7 = !operateResult2.IsSuccess;
									if (flag7)
									{
										result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
									}
									else
									{
										byte[] array = new byte[(int)length];
										bool flag8 = operateResult3.Content[25] == byte.MaxValue && operateResult3.Content[26] == 4;
										if (flag8)
										{
											Array.Copy(operateResult3.Content, 29, array, 0, (int)length);
										}
										result = OperateResult.CreateSuccessResult<byte[]>(array);
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 从西门子的PLC中读取bool数据信息，地址为"M100.0","AI100.1","I0.3","Q0.6","V100.4","S100"等，详细请参照API文档<br />
		/// Read the bool data information from Siemens PLC. The addresses are "M100.0", "AI100.1", "I0.3", "Q0.6", "V100.4", "S100", etc. For details, please Refer to API documentation
		/// </summary>
		/// <param name="address">西门子的地址数据信息</param>
		/// <param name="length">数据长度</param>
		/// <returns>带返回结果的结果对象</returns>
		// Token: 0x06000627 RID: 1575 RVA: 0x0001CE0C File Offset: 0x0001B00C
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = SiemensMPI.BuildReadCommand(this.station, address, length, true);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = this.SPSend(this.sP_ReadData, operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<bool[]>(operateResult2);
				}
				else
				{
					OperateResult<byte[]> operateResult3 = this.SPReceived(this.sP_ReadData, true);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<bool[]>(operateResult3);
					}
					else
					{
						bool flag4 = operateResult3.Content[14] != 229;
						if (flag4)
						{
							result = new OperateResult<bool[]>("PLC Receive Check Failed:" + SoftBasic.ByteToHexString(operateResult3.Content));
						}
						else
						{
							operateResult3 = this.SPReceived(this.sP_ReadData, true);
							bool flag5 = !operateResult3.IsSuccess;
							if (flag5)
							{
								result = OperateResult.CreateFailedResult<bool[]>(operateResult3);
							}
							else
							{
								bool flag6 = operateResult3.Content[19] > 0;
								if (flag6)
								{
									result = new OperateResult<bool[]>("PLC Receive Check Failed:" + operateResult3.Content[19].ToString());
								}
								else
								{
									operateResult2 = this.SPSend(this.sP_ReadData, this.readConfirm);
									bool flag7 = !operateResult2.IsSuccess;
									if (flag7)
									{
										result = OperateResult.CreateFailedResult<bool[]>(operateResult2);
									}
									else
									{
										byte[] array = new byte[operateResult3.Content.Length - 31];
										bool flag8 = operateResult3.Content[21] == byte.MaxValue && operateResult3.Content[22] == 3;
										if (flag8)
										{
											Array.Copy(operateResult3.Content, 28, array, 0, array.Length);
										}
										result = OperateResult.CreateSuccessResult<bool[]>(SoftBasic.ByteToBoolArray(array, (int)length));
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 将字节数据写入到西门子PLC中，地址为"M100.0","AI100.1","I0.3","Q0.6","V100.4","S100"等，详细请参照API文档<br />
		/// Write byte data to Siemens PLC, the address is "M100.0", "AI100.1", "I0.3", "Q0.6", "V100.4", "S100", etc. Refer to API documentation
		/// </summary>
		/// <param name="address">西门子的地址数据信息</param>
		/// <param name="value">数据长度</param>
		/// <returns>带返回结果的结果对象</returns>
		// Token: 0x06000628 RID: 1576 RVA: 0x0001CFC8 File Offset: 0x0001B1C8
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<byte[]> operateResult = SiemensMPI.BuildWriteCommand(this.station, address, value);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				bool isClearCacheBeforeRead = base.IsClearCacheBeforeRead;
				if (isClearCacheBeforeRead)
				{
					base.ClearSerialCache();
				}
				OperateResult operateResult2 = this.SPSend(this.sP_ReadData, operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
				}
				else
				{
					OperateResult<byte[]> operateResult3 = this.SPReceived(this.sP_ReadData, true);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
					}
					else
					{
						bool flag4 = operateResult3.Content[14] != 229;
						if (flag4)
						{
							result = new OperateResult<byte[]>("PLC Receive Check Failed:" + SoftBasic.ByteToHexString(operateResult3.Content));
						}
						else
						{
							operateResult3 = this.SPReceived(this.sP_ReadData, true);
							bool flag5 = !operateResult3.IsSuccess;
							if (flag5)
							{
								result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
							}
							else
							{
								bool flag6 = operateResult3.Content[25] != byte.MaxValue;
								if (flag6)
								{
									result = new OperateResult<byte[]>("PLC Receive Check Failed:" + operateResult3.Content[25].ToString());
								}
								else
								{
									operateResult2 = this.SPSend(this.sP_ReadData, this.writeConfirm);
									bool flag7 = !operateResult2.IsSuccess;
									if (flag7)
									{
										result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
									}
									else
									{
										result = OperateResult.CreateSuccessResult();
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 从西门子的PLC中读取byte数据信息，地址为"M100.0","AI100.1","I0.3","Q0.6","V100.4","S100"等，详细请参照API文档<br />
		/// Read byte data information from Siemens PLC. The addresses are "M100.0", "AI100.1", "I0.3", "Q0.6", "V100.4", "S100", etc. For details, please Refer to API documentation
		/// </summary>
		/// <param name="address">西门子的地址数据信息</param>
		/// <returns>带返回结果的结果对象</returns>
		// Token: 0x06000629 RID: 1577 RVA: 0x0001D13B File Offset: 0x0001B33B
		public OperateResult<byte> ReadByte(string address)
		{
			return ByteTransformHelper.GetResultFromArray<byte>(this.Read(address, 1));
		}

		/// <summary>
		/// 将byte数据写入到西门子PLC中，地址为"M100.0","AI100.1","I0.3","Q0.6","V100.4","S100"等，详细请参照API文档<br />
		/// Write byte data to Siemens PLC, the address is "M100.0", "AI100.1", "I0.3", "Q0.6", "V100.4", "S100", etc. API documentation
		/// </summary>
		/// <param name="address">西门子的地址数据信息</param>
		/// <param name="value">数据长度</param>
		/// <returns>带返回结果的结果对象</returns>
		// Token: 0x0600062A RID: 1578 RVA: 0x0001D14A File Offset: 0x0001B34A
		public OperateResult Write(string address, byte value)
		{
			return this.Write(address, new byte[]
			{
				value
			});
		}

		/// <inheritdoc />
		// Token: 0x0600062B RID: 1579 RVA: 0x0001D15D File Offset: 0x0001B35D
		public override string ToString()
		{
			return string.Format("SiemensMPI[{0}:{1}]", base.PortName, base.BaudRate);
		}

		/// <summary>
		/// 生成一个读取字数据指令头的通用方法<br />
		/// A general method for generating a command header to read a Word data
		/// </summary>
		/// <param name="station">设备的站号信息 -&gt; Station number information for the device</param>
		/// <param name="address">起始地址，例如M100，I0，Q0，V100 -&gt;
		/// Start address, such as M100,I0,Q0,V100</param>
		/// <param name="length">读取数据长度 -&gt; Read Data length</param>
		/// <param name="isBit">是否为位读取</param>
		/// <returns>包含结果对象的报文 -&gt; Message containing the result object</returns>
		// Token: 0x0600062C RID: 1580 RVA: 0x0001D17C File Offset: 0x0001B37C
		public static OperateResult<byte[]> BuildReadCommand(byte station, string address, ushort length, bool isBit)
		{
			OperateResult<S7AddressData> operateResult = S7AddressData.ParseFrom(address, length);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				byte[] array = new byte[38];
				array[0] = 104;
				array[1] = BitConverter.GetBytes(array.Length - 6)[0];
				array[2] = BitConverter.GetBytes(array.Length - 6)[0];
				array[3] = 104;
				array[4] = station + 128;
				array[5] = 128;
				array[6] = 124;
				array[7] = 22;
				array[8] = 1;
				array[9] = 241;
				array[10] = 0;
				array[11] = 50;
				array[12] = 1;
				array[13] = 0;
				array[14] = 0;
				array[15] = 51;
				array[16] = 2;
				array[17] = 0;
				array[18] = 14;
				array[19] = 0;
				array[20] = 0;
				array[21] = 4;
				array[22] = 1;
				array[23] = 18;
				array[24] = 10;
				array[25] = 16;
				array[26] = (isBit ? 1 : 2);
				array[27] = BitConverter.GetBytes(length)[1];
				array[28] = BitConverter.GetBytes(length)[0];
				array[29] = BitConverter.GetBytes(operateResult.Content.DbBlock)[1];
				array[30] = BitConverter.GetBytes(operateResult.Content.DbBlock)[0];
				array[31] = operateResult.Content.DataCode;
				array[32] = BitConverter.GetBytes(operateResult.Content.AddressStart)[2];
				array[33] = BitConverter.GetBytes(operateResult.Content.AddressStart)[1];
				array[34] = BitConverter.GetBytes(operateResult.Content.AddressStart)[0];
				int num = 0;
				for (int i = 4; i < 35; i++)
				{
					num += (int)array[i];
				}
				array[35] = BitConverter.GetBytes(num)[0];
				array[36] = 22;
				array[37] = 229;
				result = OperateResult.CreateSuccessResult<byte[]>(array);
			}
			return result;
		}

		/// <summary>
		/// 生成一个写入PLC数据信息的报文内容<br />
		/// Generate a message content to write PLC data information
		/// </summary>
		/// <param name="station">PLC的站号</param>
		/// <param name="address">地址</param>
		/// <param name="values">数据值</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x0600062D RID: 1581 RVA: 0x0001D348 File Offset: 0x0001B548
		public static OperateResult<byte[]> BuildWriteCommand(byte station, string address, byte[] values)
		{
			OperateResult<S7AddressData> operateResult = S7AddressData.ParseFrom(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				int num = values.Length;
				byte[] array = new byte[42 + values.Length];
				array[0] = 104;
				array[1] = BitConverter.GetBytes(array.Length - 6)[0];
				array[2] = BitConverter.GetBytes(array.Length - 6)[0];
				array[3] = 104;
				array[4] = station + 128;
				array[5] = 128;
				array[6] = 92;
				array[7] = 22;
				array[8] = 2;
				array[9] = 241;
				array[10] = 0;
				array[11] = 50;
				array[12] = 1;
				array[13] = 0;
				array[14] = 0;
				array[15] = 67;
				array[16] = 2;
				array[17] = 0;
				array[18] = 14;
				array[19] = 0;
				array[20] = (byte)(values.Length + 4);
				array[21] = 5;
				array[22] = 1;
				array[23] = 18;
				array[24] = 10;
				array[25] = 16;
				array[26] = 2;
				array[27] = BitConverter.GetBytes(num)[0];
				array[28] = BitConverter.GetBytes(num)[1];
				array[29] = BitConverter.GetBytes(operateResult.Content.DbBlock)[0];
				array[30] = BitConverter.GetBytes(operateResult.Content.DbBlock)[1];
				array[31] = operateResult.Content.DataCode;
				array[32] = BitConverter.GetBytes(operateResult.Content.AddressStart)[2];
				array[33] = BitConverter.GetBytes(operateResult.Content.AddressStart)[1];
				array[34] = BitConverter.GetBytes(operateResult.Content.AddressStart)[0];
				array[35] = 0;
				array[36] = 4;
				array[37] = BitConverter.GetBytes(num * 8)[1];
				array[38] = BitConverter.GetBytes(num * 8)[0];
				values.CopyTo(array, 39);
				int num2 = 0;
				for (int i = 4; i < array.Length - 3; i++)
				{
					num2 += (int)array[i];
				}
				array[array.Length - 3] = BitConverter.GetBytes(num2)[0];
				array[array.Length - 2] = 22;
				array[array.Length - 1] = 229;
				result = OperateResult.CreateSuccessResult<byte[]>(array);
			}
			return result;
		}

		/// <summary>
		/// 根据错误信息，获取到文本信息
		/// </summary>
		/// <param name="code">状态</param>
		/// <returns>消息文本</returns>
		// Token: 0x0600062E RID: 1582 RVA: 0x0001D558 File Offset: 0x0001B758
		public static string GetMsgFromStatus(byte code)
		{
			switch (code)
			{
			case 1:
				return "Hardware fault";
			case 2:
			case 4:
				break;
			case 3:
				return "Illegal object access";
			case 5:
				return "Invalid address(incorrent variable address)";
			case 6:
				return "Data type is not supported";
			default:
				if (code == 10)
				{
					return "Object does not exist or length error";
				}
				if (code == 255)
				{
					return "No error";
				}
				break;
			}
			return StringResources.Language.UnknownError;
		}

		/// <summary>
		/// 根据错误信息，获取到文本信息
		/// </summary>
		/// <param name="errorClass">错误类型</param>
		/// <param name="errorCode">错误代码</param>
		/// <returns>错误信息</returns>
		// Token: 0x0600062F RID: 1583 RVA: 0x0001D5DC File Offset: 0x0001B7DC
		public static string GetMsgFromStatus(byte errorClass, byte errorCode)
		{
			bool flag = errorClass == 128 && errorCode == 1;
			string result;
			if (flag)
			{
				result = "Switch\u2002in\u2002wrong\u2002position\u2002for\u2002requested\u2002operation";
			}
			else
			{
				bool flag2 = errorClass == 129 && errorCode == 4;
				if (flag2)
				{
					result = "Miscellaneous\u2002structure\u2002error\u2002in\u2002command.\u2002\u2002Command is not supportedby CPU";
				}
				else
				{
					bool flag3 = errorClass == 132 && errorCode == 4;
					if (flag3)
					{
						result = "CPU is busy processing an upload or download CPU cannot process command because of system fault condition";
					}
					else
					{
						bool flag4 = errorClass == 133 && errorCode == 0;
						if (flag4)
						{
							result = "Length fields are not correct or do not agree with the amount of data received";
						}
						else
						{
							bool flag5 = errorClass == 210;
							if (flag5)
							{
								result = "Error in upload or download command";
							}
							else
							{
								bool flag6 = errorClass == 214;
								if (flag6)
								{
									result = "Protection error(password)";
								}
								else
								{
									bool flag7 = errorClass == 220 && errorCode == 1;
									if (flag7)
									{
										result = "Error in time-of-day clock data";
									}
									else
									{
										result = StringResources.Language.UnknownError;
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		// Token: 0x0400019F RID: 415
		private byte station = 2;

		// Token: 0x040001A0 RID: 416
		private byte[] readConfirm = new byte[]
		{
			104,
			8,
			8,
			104,
			130,
			128,
			92,
			22,
			2,
			176,
			7,
			0,
			45,
			22,
			229
		};

		// Token: 0x040001A1 RID: 417
		private byte[] writeConfirm = new byte[]
		{
			104,
			8,
			8,
			104,
			130,
			128,
			124,
			22,
			2,
			176,
			7,
			0,
			77,
			22,
			229
		};
	}
}
